My Linux laptop uses full disk encryption which makes the boot process slightly more complicated.
The disk layout:
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT NAME TYPE SIZE FSTYPE MOUNTPOINT nvme0n1 disk 476.9G ├─nvme0n1p1 part 512M vfat /boot/efi ├─nvme0n1p2 part 732M ext4 /boot ├─nvme0n1p3 part 75G crypto_LUKS │ └─nvme0n1p3_crypt crypt 75G LVM2_member │ ├─vgubuntu--budgie-swap_1 lvm 9G swap [SWAP] │ └─vgubuntu--budgie-root lvm 66G ext4 / └─nvme0n1p4 part 400.7G crypto_LUKS └─mydata crypt 400.7G ext4 /DATA
The setup is as follows:
If you are using full disk encryption or encrypted root partition, a separate /boot partition is necessary. When using encryption, the boot process needs to access the necessary bootloader and kernel from an unencrypted boot partition to allow the system to access files to decrypt the encrypted partitions and start the system. This leaves the boot-loader second stage file-system unencrypted and therefore vulnerable to tampering of the GRUB configuration, Linux kernel or more likely, the initial RAM file-system (initrd.img).
However, GRUB2 is (since Jessie) able to unlock LUKS devices with its cryptomount command, which therefore enables encryption of the /boot partition as well
It is possible, in UEFI Secure Boot mode, to have every stage cryptographically signed, in which case any tampering can be detected and boot aborted. But Secure Boot and Hibernate do not work because something to do with the random signing code and keys for swap decryption.
The UEFI-based platform (i.e. what we used to know as the BIOS, but is now called UEFI) reads the partition table on the system storage and mounts the EFI System Partition (ESP).
The partition table:
nvme0n1 Device Size Type Mount /dev/nvme0n1p1 512M EFI System /boot/efi /dev/nvme0n1p2 732M Linux filesystem /boot /dev/nvme0n1p3 75G Linux filesystem (LUKS) / and [SWAP] /dev/nvme0n1p4 400G Unknown (LUKS) Steves Data
The UEFI-based platform reads the partition table on the system storage and mounts the EFI System Partition (ESP), a VFAT partition labeled with a particular globally unique identifier (GUID). The ESP contains EFI applications such as bootloaders and utility software, stored in directories specific to software vendors. The ESP is /boot/efi/, and EFI software provided by Ubuntu is stored in /boot/efi/EFI/ubuntu/
The /boot/efi/EFI/ubuntu/ directory contains grub64.efi, a version of GRUB (Grand Unified Bootloader) compiled for the EFI firmware architecture as an EFI application. In the simplest case, the EFI boot manager selects grub.efi as the default bootloader and reads it into memory.
/boot/efi/EFI: BOOT ubuntu /boot/efi/EFI/BOOT: BOOTX64.EFI fbx64.efi mmx64.efi /boot/efi/EFI/ubuntu: BOOTX64.CSV grub.cfg grubx64.efi mmx64.efi shimx64.efi
GRUB determines which operating system or kernel to start, loads it into memory, and transfers control of the machine to that operating system. It is the kernel’s job to finish the boot process, including decrypting any disks.
/boot initrd.img initrd.img-5.15.0-89-generic System.map-5.15.0-89-generic vmlinuz vmlinuz-5.15.0-89-generic grub/ /boot/grub grub.cfg
The partition /boot contains the grub config initramfs and vmlinuz.
The config file /boot/grub/grub.cfg is automatically generated by grub-mkconfig. The utility grub-mkconfig (and update-grub) runs shell scripts in /etc/grub.d. One of them is /etc/grub.d/10_linux, which uses the shell function version_find_latest to keep iterating through the list of remaining Linux kernels, from latest to oldest. It also settings from /etc/default/grub file.
To see the menus and submenus available at boot time generated by grub-mkconfig:
awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\smenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg
0 : Ubuntu
1 : Advanced options for Ubuntu
1>0 : Ubuntu, with Linux 5.15.0-89-generic
1>1 : Ubuntu, with Linux 5.15.0-89-generic (recovery mode)
1>2 : Ubuntu, with Linux 5.15.0-88-generic
1>3 : Ubuntu, with Linux 5.15.0-88-generic (recovery mode)
2 : UEFI Firmware Settings
Or for Linux Mint
awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\smenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg
0 : Linux Mint 22.1 Cinnamon
1 : Advanced options for Linux Mint 22.1 Cinnamon
From the GRUB_DEFAULT in /etc/default/grub file we can see which version of Ubuntu will boot if none selected:
/etc/default/grub # GRUB_DEFAULT="1>2" GRUB_DEFAULT=0
The actual setting for each Linux option are in the /boot/grub/grub.cfg, which is built by grub-mkconfig which runs script /etc/grub.d/10_linux referencing /etc/fstab and /etc/default/grub:
/etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/mapper/vgubuntu--budgie-swap_1"
Here is an example for Option 0:
grep vml /boot/grub/grub.cfg linux /vmlinuz-5.15.0-89-generic root=/dev/mapper/vgubuntu--budgie-root ro quiet splash resume=/dev/mapper/vgubuntu--budgie-swap_1 $vt_handoff
But /dev/mapper/vgubuntu--budgie-root is actually encrypted inside nvme0n1p3:
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,UUID NAME TYPE SIZE FSTYPE MOUNTPOINT UUID nvme0n1 disk 476.9G ├─nvme0n1p1 part 512M vfat /boot/efi 44BA-16B5 ├─nvme0n1p2 part 732M ext4 /boot ad71056c-f2c5-454b-b36a-5ec55f21b226 ├─nvme0n1p3 part 75G crypto_LU b6a7071a-e553-4e95-9544-9dc9ddcfed61 │ └─nvme0n1p3_crypt crypt 75G LVM2_memb T25pQf-qlNw-pwNV-5dvg-xOTO-KoKG-tW3CjD │ ├─vgubuntu--budgie-swap_1 │ │ lvm 9G swap [SWAP] b02b828e-f0bf-4ecb-910a-b88392056049 │ └─vgubuntu--budgie-root │ lvm 66G ext4 / c525d5a2-023a-42af-98fc-0e24b8de4aa3 └─nvme0n1p4 part 400.7G crypto_LU 06124721-121b-4b54-8884-83e439ceb10c └─mydata crypt 400.7G ext4 /DATA 74dbc8a4-f60a-4370-b89f-53d094798864
Physcial volume, volume group and logical volumes:
pvscan PV /dev/mapper/nvme0n1p3_crypt VG vgubuntu-budgie lvm2 [74.98 GiB / 0 free] Total: 1 [74.98 GiB] / in use: 1 [74.98 GiB] / in no VG: 0 [0 ] vgscan Found volume group "vgubuntu-budgie" using metadata type lvm2 lvscan ACTIVE '/dev/vgubuntu-budgie/swap_1' [9.00 GiB] inherit ACTIVE '/dev/vgubuntu-budgie/root' [65.98 GiB] inherit
So at what point is decryption done?
/etc/crypttab nvme0n1p3_crypt UUID=b6a7071a-e553-4e95-9544-9dc9ddcfed61 none luks,discard
It would seem that /etc/crypttab is copied into main/cryptroot/crypttab of initrd.img and this causes the boot kernel to prompt for a password for decryption. So /dev/mapper/vgubuntu--budgie-root is available when needed in the boot process.
initrd - is an "initial RAM disk," a temporary root filesystem used in the boot process. The initrd is loaded by the bootloader along with the kernel image and is essential for the two-stage boot process that modern Linux systems use.
To see all files packaged in an the initrd (Init Ram Disk) use the following command.
lsinitramfs "/boot/initrd.img-$(uname -r)"
Note it contains Plymouth files, the graphical loader responsible for Splash screens.
To generate a new initrd use the following command:
update-initramfs -k all -c
To update initrd after making changes use the following command:
update-initramfs -u
The next boot will use this.